package heliotrope.global
{
	import flash.display.Stage;
	import flash.utils.Dictionary;
	import flash.events.Event;

	public class GlobalEventScheduler
	{
		private static var __instance:GlobalEventScheduler;
		private var _stage:Stage;
		private var _resizeListener:Dictionary;
		private var _resizeListenerNum:int = 0;
		private var _enterFrameListener:Dictionary;
		private var _enterFrameListenerNum:int = 0;
		public function GlobalEventScheduler(pvt:PrivateClass, stage_:Stage)
		{
			_stage = stage_;
			_resizeListener = new Dictionary(true);
			_enterFrameListener = new Dictionary(true);
			
			stage_.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}

		public function addResizeListener(closure_:Function):void
		{
			if(_resizeListenerNum == 0)
			{
				_stage.addEventListener(Event.RESIZE, resizeHandler);
			}
			if(_resizeListener[closure_]) return;
			_resizeListener[closure_] = closure_;
			_resizeListenerNum++;
		}
		
		public function removeResizeListener(closure_:Function):void
		{
			if(!_resizeListener[closure_]) return;
			delete _resizeListener[closure_];
			if(--_resizeListenerNum == 0)
			{
				_stage.removeEventListener(Event.RESIZE, resizeHandler);
			}
		}

		public function addEnterFrameListener(closure_:Function):void
		{
			if(_enterFrameListenerNum == 0)
			{
				_stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			}
			if(_enterFrameListener[closure_]) return;
			_enterFrameListener[closure_] = closure_;
			_enterFrameListenerNum++;
		}
		
		public function removeEnterFrameListener(closure_:Function):void
		{
			if(!_enterFrameListener[closure_]) return;
			delete _enterFrameListener[closure_];
			if(--_enterFrameListenerNum == 0)
			{
				_stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
			}
		}

		private function resizeHandler(event:Event):void
		{
			for each(var closure:Function in _resizeListener)
			{
				closure(event);
			}
		}
		
		private function enterFrameHandler(event:Event):void
		{
			for each(var closure:Function in _enterFrameListener)
			{
				closure(event);
			}
		}
		/**
		 * The init method ensures that you know the time to instantiate the singleton class
		 * */
		public static function init(stage_:Stage):void
		{
			if(GlobalEventScheduler.__instance)
			{
				throw new Error("You can't init the GlobalEventScheduler twice!")
			}
			GlobalEventScheduler.__instance = new GlobalEventScheduler(new PrivateClass, stage_);
		}
		
		public static function getInstance():GlobalEventScheduler
		{
			if(!GlobalEventScheduler.__instance)
			{
				throw new Error("You should init the GlobalEventScheduler at first!")
			}
			return GlobalEventScheduler.__instance;
		}
	}
}

class PrivateClass
{
	public function PrivateClass()
	{
	}
}